/**
 * @file snakegamerenderer.h
 * @brief Snake游戏渲染引擎类头文件
 *
 * SnakeGameRenderer是Snake游戏的高性能渲染引擎，负责：
 * - 游戏画面的实时渲染和绘制
 * - 平滑动画效果和过渡处理
 * - 多玩家蛇的可视化显示
 * - 食物、特效、UI元素的渲染
 * - 性能优化和帧率控制
 * - 主题和视觉效果管理
 */

#ifndef SNAKEGAMERENDERER_H
#define SNAKEGAMERENDERER_H

#include <QWidget>              // Qt窗口部件基类
#include <QPainter>             // 绘图类
#include <QTimer>               // 定时器
#include <QColor>               // 颜色类
#include <QFont>                // 字体类
#include <QPixmap>              // 像素图
#include <QPropertyAnimation>   // 属性动画
#include <QEasingCurve>         // 缓动曲线
#include <QHash>                // 哈希表
#include <QQueue>               // 队列
#include "snakegamestate.h"

/**
 * @struct RenderConfig
 * @brief 渲染配置结构
 */
struct RenderConfig {
    int cellSize = 20;              ///< 单元格大小（像素）
    int gridLineWidth = 1;          ///< 网格线宽度
    bool showGrid = true;           ///< 显示网格
    bool showCoordinates = false;   ///< 显示坐标
    bool enableAnimations = true;   ///< 启用动画
    bool enableSmoothMovement = true; ///< 启用平滑移动
    bool enableParticleEffects = true; ///< 启用粒子效果
    int targetFPS = 60;             ///< 目标帧率
    double animationSpeed = 1.0;    ///< 动画速度倍数
    QString theme = "default";      ///< 主题名称
};

/**
 * @struct AnimationState
 * @brief 动画状态结构
 */
struct AnimationState {
    Position currentPos;            ///< 当前位置
    Position targetPos;             ///< 目标位置
    double progress = 0.0;          ///< 动画进度（0.0-1.0）
    qint64 startTime = 0;           ///< 动画开始时间
    int duration = 100;             ///< 动画持续时间（毫秒）
    QEasingCurve::Type easing = QEasingCurve::OutQuad; ///< 缓动类型
    bool active = false;            ///< 是否激活
};

/**
 * @struct ParticleEffect
 * @brief 粒子效果结构
 */
struct ParticleEffect {
    Position position;              ///< 粒子位置
    QColor color;                   ///< 粒子颜色
    double size = 1.0;              ///< 粒子大小
    double velocity = 1.0;          ///< 粒子速度
    double angle = 0.0;             ///< 粒子角度
    double life = 1.0;              ///< 粒子生命值（0.0-1.0）
    double decay = 0.01;            ///< 衰减速度
    QString type = "default";       ///< 粒子类型
    qint64 spawnTime = 0;           ///< 生成时间
};

/**
 * @class SnakeGameRenderer
 * @brief Snake游戏渲染引擎类
 *
 * 高性能的游戏渲染引擎，提供完整的视觉效果和动画系统。
 * 支持多种渲染模式、主题切换、性能优化等高级功能。
 */
class SnakeGameRenderer : public QWidget
{
    Q_OBJECT  // 启用Qt元对象系统

    // === 动画属性 ===
    Q_PROPERTY(double animationProgress READ getAnimationProgress WRITE setAnimationProgress)

public:
    /**
     * @enum RenderMode
     * @brief 渲染模式枚举
     */
    enum RenderMode {
        Classic = 0,                ///< 经典模式
        Modern,                     ///< 现代模式
        Minimal,                    ///< 简约模式
        Retro                       ///< 复古模式
    };
    Q_ENUM(RenderMode)

    explicit SnakeGameRenderer(QWidget *parent = nullptr);
    ~SnakeGameRenderer();

    // === 配置管理 ===
    /**
     * @brief 设置渲染配置
     * @param config 渲染配置
     */
    void setRenderConfig(const RenderConfig &config);

    /**
     * @brief 获取渲染配置
     * @return 当前渲染配置
     */
    const RenderConfig& getRenderConfig() const { return m_config; }

    /**
     * @brief 设置游戏状态
     * @param gameState 游戏状态管理器
     */
    void setGameState(SnakeGameState *gameState);

    /**
     * @brief 设置渲染模式
     * @param mode 渲染模式
     */
    void setRenderMode(RenderMode mode);

    /**
     * @brief 获取渲染模式
     * @return 当前渲染模式
     */
    RenderMode getRenderMode() const { return m_renderMode; }

    // === 主题管理 ===
    /**
     * @brief 设置主题
     * @param themeName 主题名称
     */
    void setTheme(const QString &themeName);

    /**
     * @brief 获取当前主题
     * @return 主题名称
     */
    QString getCurrentTheme() const { return m_config.theme; }

    /**
     * @brief 获取可用主题列表
     * @return 主题名称列表
     */
    QStringList getAvailableThemes() const;

    // === 动画控制 ===
    /**
     * @brief 启用/禁用动画
     * @param enabled 是否启用
     */
    void setAnimationsEnabled(bool enabled);

    /**
     * @brief 设置动画速度
     * @param speed 速度倍数（1.0为正常速度）
     */
    void setAnimationSpeed(double speed);

    /**
     * @brief 获取动画进度
     * @return 动画进度（0.0-1.0）
     */
    double getAnimationProgress() const { return m_animationProgress; }

    /**
     * @brief 设置动画进度
     * @param progress 动画进度（0.0-1.0）
     */
    void setAnimationProgress(double progress);

    // === 效果控制 ===
    /**
     * @brief 添加粒子效果
     * @param position 位置
     * @param type 效果类型
     * @param color 颜色
     */
    void addParticleEffect(const Position &position, const QString &type, const QColor &color = Qt::white);

    /**
     * @brief 清除所有粒子效果
     */
    void clearParticleEffects();

    /**
     * @brief 播放食物消费效果
     * @param position 食物位置
     * @param foodType 食物类型
     */
    void playFoodConsumedEffect(const Position &position, const QString &foodType);

    /**
     * @brief 播放蛇死亡效果
     * @param snakeBody 蛇身体位置列表
     * @param color 蛇颜色
     */
    void playSnakeDeathEffect(const QVector<Position> &snakeBody, const QColor &color);

    // === 性能监控 ===
    /**
     * @brief 获取当前FPS
     * @return 当前帧率
     */
    double getCurrentFPS() const;

    /**
     * @brief 获取渲染统计信息
     * @return 统计信息JSON对象
     */
    QJsonObject getRenderStats() const;

    // === 尺寸计算 ===
    /**
     * @brief 计算推荐窗口大小
     * @param boardWidth 游戏板宽度
     * @param boardHeight 游戏板高度
     * @return 推荐窗口大小
     */
    QSize calculateRecommendedSize(int boardWidth, int boardHeight) const;

    /**
     * @brief 像素坐标转换为游戏坐标
     * @param pixelPos 像素坐标
     * @return 游戏坐标
     */
    Position pixelToGamePosition(const QPoint &pixelPos) const;

    /**
     * @brief 游戏坐标转换为像素坐标
     * @param gamePos 游戏坐标
     * @return 像素坐标
     */
    QPoint gameToPixelPosition(const Position &gamePos) const;

signals:
    /**
     * @brief 渲染完成信号
     * @param frameTime 帧时间（毫秒）
     */
    void frameRendered(double frameTime);

    /**
     * @brief FPS更新信号
     * @param fps 当前帧率
     */
    void fpsUpdated(double fps);

    /**
     * @brief 主题改变信号
     * @param themeName 新主题名称
     */
    void themeChanged(const QString &themeName);

protected:
    // === Qt事件处理 ===
    void paintEvent(QPaintEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;

private slots:
    /**
     * @brief 动画定时器处理
     */
    void onAnimationTimer();

    /**
     * @brief FPS计算定时器处理
     */
    void onFPSTimer();

    /**
     * @brief 游戏状态更新处理
     */
    void onGameStateUpdated();

private:
    // === 核心组件 ===
    SnakeGameState *m_gameState;    ///< 游戏状态管理器
    RenderConfig m_config;          ///< 渲染配置
    RenderMode m_renderMode;        ///< 渲染模式

    // === 动画系统 ===
    QTimer *m_animationTimer;       ///< 动画定时器
    QTimer *m_fpsTimer;             ///< FPS计算定时器
    double m_animationProgress;     ///< 动画进度
    QHash<QString, AnimationState> m_snakeAnimations; ///< 蛇动画状态
    QPropertyAnimation *m_propertyAnimation; ///< 属性动画

    // === 粒子系统 ===
    QVector<ParticleEffect> m_particles; ///< 粒子效果列表
    QTimer *m_particleTimer;        ///< 粒子更新定时器

    // === 性能监控 ===
    double m_currentFPS;            ///< 当前帧率
    qint64 m_lastFrameTime;         ///< 上一帧时间
    QQueue<qint64> m_frameTimes;    ///< 帧时间队列
    int m_frameCount;               ///< 帧计数

    // === 渲染缓存 ===
    QPixmap m_backgroundCache;      ///< 背景缓存
    QPixmap m_gridCache;            ///< 网格缓存
    bool m_cacheValid;              ///< 缓存是否有效

    // === 主题数据 ===
    QHash<QString, QJsonObject> m_themes; ///< 主题数据
    QColor m_backgroundColor;       ///< 背景颜色
    QColor m_gridColor;             ///< 网格颜色
    QColor m_textColor;             ///< 文本颜色
    QFont m_gameFont;               ///< 游戏字体

    // === 私有方法 ===
    void initializeRenderer();
    void loadThemes();
    void applyTheme(const QString &themeName);
    void updateAnimations();
    void updateParticles();
    void calculateFPS();
    void invalidateCache();
    
    // === 绘制方法 ===
    void drawBackground(QPainter &painter);
    void drawGrid(QPainter &painter);
    void drawSnakes(QPainter &painter);
    void drawSnake(QPainter &painter, const SnakeData &snake);
    void drawSnakeEyes(QPainter &painter, const QRect &headRect, Direction direction, bool isAlive);
    void drawDeadSnakeEyes(QPainter &painter, const QRect &headRect);
    void drawFoods(QPainter &painter);
    void drawFood(QPainter &painter, const FoodData &food);
    void drawNormalFood(QPainter &painter, const QRect &cellRect, const QColor &baseColor);
    void drawSpecialFood(QPainter &painter, const QRect &cellRect, const QColor &baseColor);
    void drawParticles(QPainter &painter);
    void drawStarParticle(QPainter &painter, const QPointF &center, double size, const QColor &color);
    void drawExplosionParticle(QPainter &painter, const QPointF &center, double size, const QColor &color);
    void drawUI(QPainter &painter);
    void drawDebugInfo(QPainter &painter);
    
    // === 辅助方法 ===
    QColor getSnakeColor(const QString &playerId, bool isHead = false) const;
    QColor getFoodColor(const QString &foodType) const;
    QRect getCellRect(const Position &pos) const;
    QRect getCellRect(int x, int y) const;
    void setupPainter(QPainter &painter);
    Position interpolatePosition(const Position &from, const Position &to, double progress) const;
};

#endif // SNAKEGAMERENDERER_H
